package cn.yto.print.utils;

import cn.yto.print.config.CaffeineCacheConfig;
import cn.yto.print.model.dto.PrintCacheDTO;
import cn.yto.print.model.request.PrintTaskRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class PrintTaskUtil {

    private static final Logger logger = LoggerFactory.getLogger(PrintTaskUtil.class);

    private static final int MAXIMUM_GROUP_SIZE = 10;

    /**
     * 按平台分组聚合数据
     */
    public static List<List<PrintTaskRequest.Document>> groupConsecutiveByPlatform(List<PrintTaskRequest.Document> dataList) {
        List<List<PrintTaskRequest.Document>> finalGroups = new ArrayList<>();
        List<PrintTaskRequest.Document> currentGroup = new ArrayList<>();
        String currentPlatform = null;
        for (PrintTaskRequest.Document doc : dataList) {
            String docPlatform = doc.getExpressPrintType();
            boolean newGroupFlag = (currentGroup.isEmpty()) || (!docPlatform.equals(currentPlatform))
                    || (currentGroup.size() >= MAXIMUM_GROUP_SIZE);
            if (newGroupFlag) {
                if (!currentGroup.isEmpty()) {
                    finalGroups.add(new ArrayList<>(currentGroup));
                    currentGroup.clear();
                }
                currentPlatform = docPlatform;
            }
            currentGroup.add(doc);
        }
        if (!currentGroup.isEmpty()) {
            finalGroups.add(currentGroup);
        }
        logger.info("打印数据按平台分组完成，共生成 {} 个小组", finalGroups.size());
        return finalGroups;
    }

    /**
     * 按平台+打印机分组
     */
    public static List<List<PrintTaskRequest.Document>> groupConsecutiveByPrinter(String defaultPrinter, List<PrintTaskRequest.Document> dataList) {
        List<List<PrintTaskRequest.Document>> mergedGroups = new ArrayList<>();
        // 先进行平台分组
        List<List<PrintTaskRequest.Document>> platformGroups = groupConsecutiveByPlatformExt(dataList);
        for (List<PrintTaskRequest.Document> platformGroup : platformGroups) {
            List<PrintTaskRequest.Document> currentPrinterGroup = new ArrayList<>();
            String currentPrinter = null;

            for (PrintTaskRequest.Document doc : platformGroup) {
                String chosenPrinter = StringUtils.isBlank(doc.getPrinter()) ? defaultPrinter : doc.getPrinter();
                doc.setPrinter(chosenPrinter);
                boolean newPrinterGroup = currentPrinterGroup.isEmpty() || (!chosenPrinter.equals(currentPrinter))
                        || (currentPrinterGroup.size() >= MAXIMUM_GROUP_SIZE);
                if (newPrinterGroup) {
                    if (!currentPrinterGroup.isEmpty()) {
                        mergedGroups.add(new ArrayList<>(currentPrinterGroup));
                        currentPrinterGroup.clear();
                    }
                    currentPrinter = chosenPrinter;
                }
                currentPrinterGroup.add(doc);
            }
            if (!currentPrinterGroup.isEmpty()) {
                mergedGroups.add(new ArrayList<>(currentPrinterGroup));
            }
        }
        logger.info("打印数据按打印机分组完成，共生成 {} 个小组", mergedGroups.size());
        return mergedGroups;
    }

    private static List<List<PrintTaskRequest.Document>> groupConsecutiveByPlatformExt(List<PrintTaskRequest.Document> dataList) {
        List<List<PrintTaskRequest.Document>> platformGroups = new ArrayList<>();
        List<PrintTaskRequest.Document> currentGroup = new ArrayList<>();
        String lastPlatform = null;
        for (PrintTaskRequest.Document doc : dataList) {
            String docPlatform = doc.getExpressPrintType();
            if (currentGroup.isEmpty() || !docPlatform.equals(lastPlatform)) {
                if (!currentGroup.isEmpty()) {
                    platformGroups.add(new ArrayList<>(currentGroup));
                    currentGroup.clear();
                }
                lastPlatform = docPlatform;
            }
            currentGroup.add(doc);
        }
        if (!currentGroup.isEmpty()) {
            platformGroups.add(currentGroup);
        }
        return platformGroups;
    }

    /**
     * 按打印机分组
     */
    public static List<List<PrintTaskRequest.Document>> groupConsecutiveByPrinterExt(int firstDocumentNumber, String defaultPrinter, List<PrintTaskRequest.Document> dataList) {
        int startNum = firstDocumentNumber <= 0 ? 1 : firstDocumentNumber;
        AtomicInteger docCounter = new AtomicInteger(startNum);
        Map<String, List<PrintTaskRequest.Document>> printerMap = new HashMap<>();
        for (PrintTaskRequest.Document doc : dataList) {
            String printer = StringUtils.isBlank(doc.getPrinter()) ? defaultPrinter : doc.getPrinter();
            doc.setPrinter(printer);
            doc.setDocumentNumber(docCounter.getAndIncrement());
            printerMap.computeIfAbsent(printer, k -> new ArrayList<>()).add(doc);
        }
        List<List<PrintTaskRequest.Document>> groupedList = new ArrayList<>(printerMap.values());
        logger.info("打印数据按打印机分组完成，共生成 {} 个小组", groupedList.size());
        return groupedList;
    }

    /**
     * 按平台分组
     */
    public static List<List<PrintTaskRequest.Document>> groupConsecutiveByPlatformNum(List<PrintTaskRequest.Document> dataList) {
        List<List<PrintTaskRequest.Document>> groups = new ArrayList<>();
        List<PrintTaskRequest.Document> currentGroup = new ArrayList<>();
        String lastPlatform = null;
        int lastNumber = -1;
        for (PrintTaskRequest.Document doc : dataList) {
            String platform = doc.getExpressPrintType();
            int docNum = doc.getDocumentNumber();
            boolean startNew = currentGroup.isEmpty() || (!platform.equals(lastPlatform))
                    || (lastNumber != docNum - 1) || (currentGroup.size() >= MAXIMUM_GROUP_SIZE);
            if (startNew) {
                if (!currentGroup.isEmpty()) {
                    groups.add(new ArrayList<>(currentGroup));
                    currentGroup.clear();
                }
                lastPlatform = platform;
            }
            currentGroup.add(doc);
            lastNumber = docNum;
        }
        if (!currentGroup.isEmpty()) {
            groups.add(currentGroup);
        }
        logger.info("---> 打印数据按平台二次分组完成，共生成 {} 个小组", groups.size());
        return groups;
    }

    /**
     * 添加缓存
     */
    public static void addPrintTaskCache(PrintTaskRequest printParam) {
        List<String> docIds = printParam.getDocuments().stream()
                .map(PrintTaskRequest.Document::getDocumentID).collect(Collectors.toList());
        PrintCacheDTO cacheObj = new PrintCacheDTO();
        cacheObj.setTemplateType(printParam.getTemplateType());
        cacheObj.setSessionId(printParam.getSessionId());
        cacheObj.setDocumentIds(docIds);
        CaffeineCacheConfig.getPrintCache().put(printParam.getTaskId(), cacheObj);
    }

    /**
     * 生成6位随机大写字母+数字
     */
    public static String generateRandom() {
        final String CHAR_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder(6);
        for (int i = 0; i < 6; i++) {
            int idx = random.nextInt(CHAR_SET.length());
            sb.append(CHAR_SET.charAt(idx));
        }
        return sb.toString();
    }

}

